}
static gboolean
-thaw_clock_cb (GdkFrameClock *clock)
+thaw_updates_cb (GdkSurface *surface)
{
- _gdk_frame_clock_thaw (clock);
- g_object_unref (clock);
+ gdk_surface_thaw_updates (surface);
+ g_object_unref (surface);
return G_SOURCE_REMOVE;
}
/* If there is no remote web client, rate limit update to once a second */
if (local_reply)
- g_timeout_add_seconds (1, (GSourceFunc)thaw_clock_cb, g_object_ref (clock));
+ g_timeout_add_seconds (1, (GSourceFunc)thaw_updates_cb, g_object_ref (surface));
else
- _gdk_frame_clock_thaw (clock);
+ gdk_surface_thaw_updates (surface);
if (timings)
{
GdkBroadwayDisplay *broadway_display;
impl->pending_frame_counter = gdk_frame_clock_get_frame_counter (clock);
- _gdk_frame_clock_freeze (gdk_surface_get_frame_clock (surface));
+ gdk_surface_freeze_updates (surface);
broadway_display = GDK_BROADWAY_DISPLAY (display);
gint n_timings;
gint current;
GdkFrameTimings *timings[FRAME_HISTORY_MAX_LENGTH];
+ gint n_freeze_inhibitors;
};
G_DEFINE_ABSTRACT_TYPE_WITH_PRIVATE (GdkFrameClock, gdk_frame_clock, G_TYPE_OBJECT)
+static void
+_gdk_frame_clock_freeze (GdkFrameClock *clock);
+
static void
gdk_frame_clock_finalize (GObject *object)
{
G_OBJECT_CLASS (gdk_frame_clock_parent_class)->finalize (object);
}
+static void
+gdk_frame_clock_constructed (GObject *object)
+{
+ G_OBJECT_CLASS (gdk_frame_clock_parent_class)->constructed (object);
+
+ _gdk_frame_clock_freeze (GDK_FRAME_CLOCK (object));
+}
+
static void
gdk_frame_clock_class_init (GdkFrameClockClass *klass)
{
GObjectClass *gobject_class = (GObjectClass*) klass;
gobject_class->finalize = gdk_frame_clock_finalize;
+ gobject_class->constructed = gdk_frame_clock_constructed;
/**
* GdkFrameClock::flush-events:
GDK_FRAME_CLOCK_GET_CLASS (frame_clock)->end_updating (frame_clock);
}
-void
+static void
_gdk_frame_clock_freeze (GdkFrameClock *clock)
{
g_return_if_fail (GDK_IS_FRAME_CLOCK (clock));
}
-void
+static void
_gdk_frame_clock_thaw (GdkFrameClock *clock)
{
g_return_if_fail (GDK_IS_FRAME_CLOCK (clock));
GDK_FRAME_CLOCK_GET_CLASS (clock)->thaw (clock);
}
+void
+_gdk_frame_clock_inhibit_freeze (GdkFrameClock *clock)
+{
+ GdkFrameClockPrivate *priv;
+
+ g_return_if_fail (GDK_IS_FRAME_CLOCK (clock));
+
+ priv = clock->priv;
+
+ priv->n_freeze_inhibitors++;
+ if (priv->n_freeze_inhibitors == 1)
+ _gdk_frame_clock_thaw (clock);
+}
+
+
+void
+_gdk_frame_clock_uninhibit_freeze (GdkFrameClock *clock)
+{
+ GdkFrameClockPrivate *priv;
+
+ g_return_if_fail (GDK_IS_FRAME_CLOCK (clock));
+
+ priv = clock->priv;
+
+ priv->n_freeze_inhibitors--;
+ if (priv->n_freeze_inhibitors == 0)
+ _gdk_frame_clock_freeze (clock);
+}
+
/**
* gdk_frame_clock_get_frame_counter:
* @frame_clock: a #GdkFrameClock
guint slept_before : 1;
};
-void _gdk_frame_clock_freeze (GdkFrameClock *clock);
-void _gdk_frame_clock_thaw (GdkFrameClock *clock);
+void _gdk_frame_clock_inhibit_freeze (GdkFrameClock *clock);
+void _gdk_frame_clock_uninhibit_freeze (GdkFrameClock *clock);
void _gdk_frame_clock_begin_frame (GdkFrameClock *clock);
void _gdk_frame_clock_debug_print_timings (GdkFrameClock *clock,
{
GdkFrameClock *frame_clock;
- if (surface &&
- (surface->update_freeze_count ||
- gdk_surface_is_toplevel_frozen (surface)))
- return;
+ g_return_if_fail (surface);
+
+ if (surface->update_freeze_count ||
+ gdk_surface_is_toplevel_frozen (surface))
+ {
+ surface->pending_schedule_update = TRUE;
+ return;
+ }
/* If there's no frame clock (a foreign surface), then the invalid
* region will just stick around unless gdk_surface_process_updates()
g_return_if_fail (GDK_IS_SURFACE (surface));
surface->update_freeze_count++;
+ if (surface->update_freeze_count == 1)
+ _gdk_frame_clock_uninhibit_freeze (surface->frame_clock);
}
/**
* gdk_surface_thaw_updates:
* @surface: a #GdkSurface
*
- * Thaws a surface frozen with gdk_surface_freeze_updates().
+ * Thaws a surface frozen with gdk_surface_freeze_updates(). Note that this
+ * will not necessarily schedule updates if the surface freeze count reaches
+ * zero.
**/
void
gdk_surface_thaw_updates (GdkSurface *surface)
g_return_if_fail (surface->update_freeze_count > 0);
if (--surface->update_freeze_count == 0)
- gdk_surface_schedule_update (surface);
+ {
+ _gdk_frame_clock_inhibit_freeze (surface->frame_clock);
+
+ if (surface->pending_schedule_update)
+ {
+ surface->pending_schedule_update = FALSE;
+ gdk_surface_schedule_update (surface);
+ }
+ }
}
void
g_return_if_fail (GDK_IS_SURFACE (surface));
surface->update_and_descendants_freeze_count++;
- _gdk_frame_clock_freeze (gdk_surface_get_frame_clock (surface));
+ gdk_surface_freeze_updates (surface);
}
void
g_return_if_fail (surface->update_and_descendants_freeze_count > 0);
surface->update_and_descendants_freeze_count--;
- _gdk_frame_clock_thaw (gdk_surface_get_frame_clock (surface));
-
gdk_surface_schedule_update (surface);
+ gdk_surface_thaw_updates (surface);
+
}
/**
G_CALLBACK (gdk_surface_paint_on_clock),
surface);
}
+
+ if (surface->update_freeze_count == 0)
+ _gdk_frame_clock_inhibit_freeze (clock);
}
if (surface->frame_clock)
G_CALLBACK (gdk_surface_paint_on_clock),
surface);
}
+
+ if (surface->update_freeze_count == 0)
+ _gdk_frame_clock_uninhibit_freeze (surface->frame_clock);
+
g_object_unref (surface->frame_clock);
}
cairo_region_t *update_area;
guint update_freeze_count;
+ gboolean pending_schedule_update;
/* This is the update_area that was in effect when the current expose
started. It may be smaller than the expose area if we'e painting
more than we have to, but it represents the "true" damage. */
return;
impl->awaiting_frame = FALSE;
- _gdk_frame_clock_thaw (clock);
+ gdk_surface_thaw_updates (surface);
timings = gdk_frame_clock_get_timings (clock, impl->pending_frame_counter);
impl->pending_frame_counter = 0;
g_signal_emit (impl, signals[COMMITTED], 0);
}
- if (impl->awaiting_frame)
- _gdk_frame_clock_freeze (clock);
+ if (impl->awaiting_frame &&
+ impl->pending_frame_counter == gdk_frame_clock_get_frame_counter (clock))
+ gdk_surface_freeze_updates (surface);
}
void
if (impl->awaiting_frame)
{
- GdkFrameClock *frame_clock;
-
impl->awaiting_frame = FALSE;
- frame_clock = gdk_surface_get_frame_clock (surface);
- if (frame_clock)
- _gdk_frame_clock_thaw (frame_clock);
+ gdk_surface_thaw_updates (surface);
}
if (impl->display_server.gtk_surface)
surface_impl->toplevel->frame_pending)
{
surface_impl->toplevel->frame_pending = FALSE;
- _gdk_frame_clock_thaw (gdk_surface_get_frame_clock (event->any.surface));
+ gdk_surface_thaw_updates (event->any.surface);
}
if (toplevel)
if (surface_impl->toplevel->frame_pending)
{
surface_impl->toplevel->frame_pending = FALSE;
- _gdk_frame_clock_thaw (clock);
+ gdk_surface_thaw_updates (event->any.surface);
}
gdk_frame_clock_get_refresh_info (clock,
g_intern_static_string ("_NET_WM_FRAME_DRAWN")))
{
impl->toplevel->frame_pending = TRUE;
- _gdk_frame_clock_freeze (gdk_surface_get_frame_clock (surface));
+ gdk_surface_freeze_updates (surface);
timings->cookie = impl->toplevel->current_counter_value;
}
}